﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ITnmg.HexConvert;
using NLog;
using NLog.Targets;

namespace sluan
{
    public partial class MainForm : Form
    {
        private GroupBox gbOther;
        private GroupBox gbReceive;
        private GroupBox gbSend;
        private Label label1;
        private Label label2;
        private Label labRxCnt;
        private Label labTxCnt;
        private Button btnClrCnt;
        private GroupBox groupBox1;
        private IContainer components;
        private int _rxCount = 10;
        private GroupBox gbPort;
        private UI.CSerialPanel SerialPanel;
        private TextBox rtbReceive;
        private Button btnSend;
        private TextBox rtbSend;
        private CheckBox cbHexSend;
        private CheckBox cbHexRecieve;
        private CheckBox cbTimeStamp;
        private Button btnClrTx;
        private Button btnClrRx;
        private int _txCount = 0;
        private Logger _logger;

        public MainForm()
        {
            InitializeComponent();
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool LockWindowUpdate(IntPtr hWndLock);

        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            this.gbOther = new System.Windows.Forms.GroupBox();
            this.btnClrTx = new System.Windows.Forms.Button();
            this.btnClrRx = new System.Windows.Forms.Button();
            this.cbTimeStamp = new System.Windows.Forms.CheckBox();
            this.cbHexSend = new System.Windows.Forms.CheckBox();
            this.cbHexRecieve = new System.Windows.Forms.CheckBox();
            this.gbReceive = new System.Windows.Forms.GroupBox();
            this.rtbReceive = new System.Windows.Forms.TextBox();
            this.gbSend = new System.Windows.Forms.GroupBox();
            this.btnSend = new System.Windows.Forms.Button();
            this.rtbSend = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.labRxCnt = new System.Windows.Forms.Label();
            this.labTxCnt = new System.Windows.Forms.Label();
            this.btnClrCnt = new System.Windows.Forms.Button();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.gbPort = new System.Windows.Forms.GroupBox();
            this.SerialPanel = new sluan.UI.CSerialPanel();
            this.gbOther.SuspendLayout();
            this.gbReceive.SuspendLayout();
            this.gbSend.SuspendLayout();
            this.groupBox1.SuspendLayout();
            this.gbPort.SuspendLayout();
            this.SuspendLayout();
            // 
            // gbOther
            // 
            this.gbOther.Controls.Add(this.btnClrTx);
            this.gbOther.Controls.Add(this.btnClrRx);
            this.gbOther.Controls.Add(this.cbTimeStamp);
            this.gbOther.Controls.Add(this.cbHexSend);
            this.gbOther.Controls.Add(this.cbHexRecieve);
            this.gbOther.Location = new System.Drawing.Point(12, 191);
            this.gbOther.Name = "gbOther";
            this.gbOther.Size = new System.Drawing.Size(165, 395);
            this.gbOther.TabIndex = 1;
            this.gbOther.TabStop = false;
            this.gbOther.Text = "Other";
            // 
            // btnClrTx
            // 
            this.btnClrTx.Location = new System.Drawing.Point(69, 116);
            this.btnClrTx.Name = "btnClrTx";
            this.btnClrTx.Size = new System.Drawing.Size(75, 23);
            this.btnClrTx.TabIndex = 15;
            this.btnClrTx.Text = "ClrTX";
            this.btnClrTx.UseVisualStyleBackColor = true;
            this.btnClrTx.Click += new System.EventHandler(this.btnClrTx_Click);
            // 
            // btnClrRx
            // 
            this.btnClrRx.Location = new System.Drawing.Point(69, 87);
            this.btnClrRx.Name = "btnClrRx";
            this.btnClrRx.Size = new System.Drawing.Size(75, 23);
            this.btnClrRx.TabIndex = 14;
            this.btnClrRx.Text = "ClrRX";
            this.btnClrRx.UseVisualStyleBackColor = true;
            this.btnClrRx.Click += new System.EventHandler(this.btnClrRx_Click);
            // 
            // cbTimeStamp
            // 
            this.cbTimeStamp.AutoSize = true;
            this.cbTimeStamp.Location = new System.Drawing.Point(69, 64);
            this.cbTimeStamp.Name = "cbTimeStamp";
            this.cbTimeStamp.Size = new System.Drawing.Size(78, 16);
            this.cbTimeStamp.TabIndex = 13;
            this.cbTimeStamp.Text = "TimeStamp";
            this.cbTimeStamp.UseVisualStyleBackColor = true;
            this.cbTimeStamp.CheckedChanged += new System.EventHandler(this.cbTimeStamp_CheckedChanged);
            // 
            // cbHexSend
            // 
            this.cbHexSend.AutoSize = true;
            this.cbHexSend.Location = new System.Drawing.Point(69, 42);
            this.cbHexSend.Name = "cbHexSend";
            this.cbHexSend.Size = new System.Drawing.Size(72, 16);
            this.cbHexSend.TabIndex = 12;
            this.cbHexSend.Text = "HEX Send";
            this.cbHexSend.UseVisualStyleBackColor = true;
            this.cbHexSend.CheckedChanged += new System.EventHandler(this.cbHexSend_CheckedChanged);
            // 
            // cbHexRecieve
            // 
            this.cbHexRecieve.AutoSize = true;
            this.cbHexRecieve.Location = new System.Drawing.Point(69, 20);
            this.cbHexRecieve.Name = "cbHexRecieve";
            this.cbHexRecieve.Size = new System.Drawing.Size(90, 16);
            this.cbHexRecieve.TabIndex = 11;
            this.cbHexRecieve.Text = "HEX Receive";
            this.cbHexRecieve.UseVisualStyleBackColor = true;
            this.cbHexRecieve.CheckedChanged += new System.EventHandler(this.cbHexRecieve_CheckedChanged);
            // 
            // gbReceive
            // 
            this.gbReceive.Controls.Add(this.rtbReceive);
            this.gbReceive.Location = new System.Drawing.Point(183, 12);
            this.gbReceive.Name = "gbReceive";
            this.gbReceive.Size = new System.Drawing.Size(688, 439);
            this.gbReceive.TabIndex = 2;
            this.gbReceive.TabStop = false;
            this.gbReceive.Text = "Receive";
            // 
            // rtbReceive
            // 
            this.rtbReceive.AcceptsReturn = true;
            this.rtbReceive.AcceptsTab = true;
            this.rtbReceive.Location = new System.Drawing.Point(7, 21);
            this.rtbReceive.MaxLength = 1024;
            this.rtbReceive.Multiline = true;
            this.rtbReceive.Name = "rtbReceive";
            this.rtbReceive.ReadOnly = true;
            this.rtbReceive.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.rtbReceive.Size = new System.Drawing.Size(675, 418);
            this.rtbReceive.TabIndex = 0;
            this.rtbReceive.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.rtbReceive_KeyPress);
            // 
            // gbSend
            // 
            this.gbSend.Controls.Add(this.btnSend);
            this.gbSend.Controls.Add(this.rtbSend);
            this.gbSend.Location = new System.Drawing.Point(183, 457);
            this.gbSend.Name = "gbSend";
            this.gbSend.Size = new System.Drawing.Size(688, 93);
            this.gbSend.TabIndex = 3;
            this.gbSend.TabStop = false;
            this.gbSend.Text = "Send";
            // 
            // btnSend
            // 
            this.btnSend.Location = new System.Drawing.Point(606, 21);
            this.btnSend.Name = "btnSend";
            this.btnSend.Size = new System.Drawing.Size(75, 66);
            this.btnSend.TabIndex = 1;
            this.btnSend.Text = "Send";
            this.btnSend.UseVisualStyleBackColor = true;
            this.btnSend.Click += new System.EventHandler(this.btnSend_Click);
            // 
            // rtbSend
            // 
            this.rtbSend.AcceptsTab = true;
            this.rtbSend.Location = new System.Drawing.Point(7, 21);
            this.rtbSend.MaxLength = 10480;
            this.rtbSend.Multiline = true;
            this.rtbSend.Name = "rtbSend";
            this.rtbSend.Size = new System.Drawing.Size(592, 66);
            this.rtbSend.TabIndex = 0;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(434, 15);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(23, 12);
            this.label1.TabIndex = 4;
            this.label1.Text = "RX:";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(506, 15);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(23, 12);
            this.label2.TabIndex = 5;
            this.label2.Text = "TX:";
            // 
            // labRxCnt
            // 
            this.labRxCnt.AutoSize = true;
            this.labRxCnt.Location = new System.Drawing.Point(457, 15);
            this.labRxCnt.Name = "labRxCnt";
            this.labRxCnt.Size = new System.Drawing.Size(11, 12);
            this.labRxCnt.TabIndex = 6;
            this.labRxCnt.Text = "0";
            // 
            // labTxCnt
            // 
            this.labTxCnt.AutoSize = true;
            this.labTxCnt.Location = new System.Drawing.Point(530, 15);
            this.labTxCnt.Name = "labTxCnt";
            this.labTxCnt.Size = new System.Drawing.Size(11, 12);
            this.labTxCnt.TabIndex = 7;
            this.labTxCnt.Text = "0";
            // 
            // btnClrCnt
            // 
            this.btnClrCnt.Location = new System.Drawing.Point(374, 7);
            this.btnClrCnt.Name = "btnClrCnt";
            this.btnClrCnt.Size = new System.Drawing.Size(52, 23);
            this.btnClrCnt.TabIndex = 8;
            this.btnClrCnt.Text = "ClrCnt";
            this.btnClrCnt.UseVisualStyleBackColor = true;
            this.btnClrCnt.Click += new System.EventHandler(this.btnClrCnt_Click);
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.btnClrCnt);
            this.groupBox1.Controls.Add(this.labTxCnt);
            this.groupBox1.Controls.Add(this.label2);
            this.groupBox1.Controls.Add(this.labRxCnt);
            this.groupBox1.Controls.Add(this.label1);
            this.groupBox1.Location = new System.Drawing.Point(183, 556);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(688, 30);
            this.groupBox1.TabIndex = 9;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Satus";
            // 
            // gbPort
            // 
            this.gbPort.Controls.Add(this.SerialPanel);
            this.gbPort.Location = new System.Drawing.Point(12, 12);
            this.gbPort.Name = "gbPort";
            this.gbPort.Size = new System.Drawing.Size(165, 173);
            this.gbPort.TabIndex = 0;
            this.gbPort.TabStop = false;
            this.gbPort.Text = "Port";
            // 
            // SerialPanel
            // 
            this.SerialPanel.Location = new System.Drawing.Point(9, 11);
            this.SerialPanel.Name = "SerialPanel";
            this.SerialPanel.Port = null;
            this.SerialPanel.Size = new System.Drawing.Size(150, 150);
            this.SerialPanel.TabIndex = 0;
            // 
            // MainForm
            // 
            this.ClientSize = new System.Drawing.Size(883, 598);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.gbSend);
            this.Controls.Add(this.gbReceive);
            this.Controls.Add(this.gbOther);
            this.Controls.Add(this.gbPort);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.Name = "MainForm";
            this.Text = "Sluan Com Test";
            this.Load += new System.EventHandler(this.MainForm_Load);
            this.gbOther.ResumeLayout(false);
            this.gbOther.PerformLayout();
            this.gbReceive.ResumeLayout(false);
            this.gbReceive.PerformLayout();
            this.gbSend.ResumeLayout(false);
            this.gbSend.PerformLayout();
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.gbPort.ResumeLayout(false);
            this.ResumeLayout(false);

        }



        private void PortOpened_Event(object sender, EventArgs e)
        {
            btnSend.Enabled = true;
            //bind the event handle to data receive
            SerialPanel.Port.DataReceived += Port_DataReceived;
        }

        private void Port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                SerialPort port = sender as SerialPort;
                string rx = port.ReadExisting();
                this._rxCount += rx.Length;
                string prefix = "";
                //check hex
                if (cbHexRecieve.Checked)
                {
                    byte[] bvalue = System.Text.ASCIIEncoding.ASCII.GetBytes(rx);
                    rx = HexConvert.ToHexString(bvalue);
                    //last char is space or "\r" "\n"
                    if (!string.IsNullOrEmpty(rtbReceive.Text))
                    {
                        if (!rtbReceive.Text.EndsWith(" "))
                        {
                            prefix = " ";
                        }
                    }
                }
                //Add time stamp
                if (cbTimeStamp.Checked)
                {
                    //
                    DateTime datetime = DateTime.Now;
                    prefix = datetime.ToString("\r\n[yy-mm-dd HH:mm:ss fff]");
                }

                rx = prefix + rx;
                if (this.InvokeRequired)
                {
                    this.Invoke(new Action(() =>
                    {
                        if (this.rtbReceive.Text.Length > 10240)
                        {
                            try
                            {
                                LockWindowUpdate(rtbReceive.Handle);
                                this.rtbReceive.Text = this.rtbReceive.Text.Substring(this.rtbReceive.Text.Length - 10240);
                                this.rtbReceive.AppendText(rx);
                            }
                            finally
                            {
                                LockWindowUpdate(IntPtr.Zero);
                            }

                        }
                        else
                        {
                            this.rtbReceive.AppendText(rx);
                        }
                        _logger.Info(rx);
                        this.labRxCnt.Text = "" + this._rxCount;
                    }));
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void PortClosed_Event(object sender, EventArgs e)
        {
            btnSend.Enabled = false;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            btnSend.Enabled = false;

            SerialPanel.PortClosed = PortClosed_Event;
            SerialPanel.PortOpened = PortOpened_Event;

            //logger
            var config = new NLog.Config.LoggingConfiguration();
            var logfile = new NLog.Targets.FileTarget("logfile")
            {
                FileName = "log.txt",
                Layout = "${message}",
                LineEnding = LineEndingMode.None
            };
            config.AddRule(LogLevel.Info, LogLevel.Fatal, logfile);


            NLog.LogManager.Configuration = config;

            _logger = NLog.LogManager.GetLogger("logfile");
            _logger.Info("\r\n-------Logger begin:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "--------\r\n");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            //do stuff with send
            //do with  string
            string str = rtbSend.Text;
            if (string.IsNullOrEmpty(str))
            {
                //nothing to do
                return;

            }
            if (cbHexSend.Checked)
            {
                try
                {
                    byte[] bvalue = HexConvert.ToBytes(str);
                    if (bvalue.Length > 0)
                    {
                        SerialPanel.Port.Write(bvalue, 0, bvalue.Length);
                        this._txCount += bvalue.Length;
                        this.labTxCnt.Text = "" + this._txCount;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                //just put out
                Console.WriteLine("Send string: " + str);
                try
                {
                    SerialPanel.Port.Write(str);
                    this._txCount += str.Length;
                    this.labTxCnt.Text = "" + this._txCount;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    //post msg to the button 
                    SerialPanel.Exception_close();
                }
            }
        }

        private void cbHexSend_CheckedChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(rtbSend.Text))
            {
                //nothing to do
                return;
            }
            //
            CheckBox cbbtn = sender as CheckBox;
            if (cbbtn.Checked)
            {
                //string to hex
                byte[] bvalue = System.Text.ASCIIEncoding.ASCII.GetBytes(rtbSend.Text);
                string str = HexConvert.ToHexString(bvalue);
                rtbSend.Text = str;
            }
            else
            {
                //hex to string
                try
                {
                    byte[] bvalue = HexConvert.ToBytes(rtbSend.Text);
                    string str = System.Text.ASCIIEncoding.ASCII.GetString(bvalue);
                    rtbSend.Text = str;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    cbHexSend.CheckedChanged -= new System.EventHandler(this.cbHexSend_CheckedChanged);
                    //this line will call this func again ,so unbind the event hander
                    cbbtn.CheckState = CheckState.Checked;
                    cbHexSend.CheckedChanged += new System.EventHandler(this.cbHexSend_CheckedChanged);
                }

            }
        }

        private void cbHexRecieve_CheckedChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(rtbReceive.Text))
            {
                //nothing to do
                return;
            }
            //
            CheckBox cbbtn = sender as CheckBox;
            if (cbbtn.Checked)
            {
                //string to hex
                byte[] bvalue = System.Text.ASCIIEncoding.ASCII.GetBytes(rtbReceive.Text);
                string str = HexConvert.ToHexString(bvalue);
                rtbReceive.Text = str;
            }
            else
            {
                //hex to string
                try
                {
                    byte[] bvalue = HexConvert.ToBytes(rtbReceive.Text);
                    string str = System.Text.ASCIIEncoding.ASCII.GetString(bvalue);
                    rtbReceive.Text = str;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Ex for hex send " + ex.Message);
                }
            }
        }

        private void btnClrCnt_Click(object sender, EventArgs e)
        {
            this._rxCount = 0;
            this._txCount = 0;

            labRxCnt.Text = "0";
            labTxCnt.Text = "0";

        }

        private void cbTimeStamp_CheckedChanged(object sender, EventArgs e)
        {
            //nothing to do
        }

        private void rtbReceive_KeyPress(object sender, KeyPressEventArgs e)
        {
            //
            char[] chs = new char[10];
            chs[0] = e.KeyChar;

            int charlen = 1;

            if ((int)chs[0] == 13)
            {
                chs[0] = (char)13;
                chs[1] = (char)10;
                charlen = 2;
            }

            Console.WriteLine("char" + e.KeyChar);

            try
            {
                if (btnSend.Enabled)
                {
                    this.SerialPanel.Port.Write(chs, 0, charlen);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnClrRx_Click(object sender, EventArgs e)
        {
            rtbReceive.Text = "";
        }

        private void btnClrTx_Click(object sender, EventArgs e)
        {
            rtbSend.Text = "";
        }
    }
}
